package boundarys;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;

import common.CheckBoxJList;
import common.CheckBoxObject;
import controllers.AddClientController;
import controllers.MaintainingResidentialAreaController;
import controllers.ManageCategoriesController;
import controllers.UpdateClientController;
import entitys.Area;
import entitys.Category;
import entitys.Customer;
import entitys.Reply;
import enums.Command;
import enums.Result;

public class AddClientGUI extends AbstractGUI{

	private JFrame frmManageClients;
	private JTextField FirstnameTextField;
	private JTextField LastnameTextField;
	private JTextField PhoneTextField;
	private JTextField EmailTextField;
	private JTextField IDTextField;
	private JTextField BirthtextField;
	private JComboBox areacomboBox;
	private ArrayList<Area> areasList;
	private JComboBox comboBox;
	private ArrayList<Customer> res;
	private ArrayList<Category> result;
	private CheckBoxJList CategoryCheckboxList;
	private ArrayList<CheckBoxObject> CategoryList;
	private DefaultListModel defModel;
	private JScrollPane scroller;
	
	/**
	 * Add client GUI constructor. 
	 * This method initializes the window,buttons, labels etc...
	 */
	public AddClientGUI() {
		initialize();
		initGUI(frmManageClients);
		}

	/**
	 * Initialize the contents of the frame.
	 * Set up each components size, location etc...
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void initialize() {
		frmManageClients = new JFrame();
		frmManageClients.getContentPane().addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if(EmailTextField.getText().isEmpty())
				{
					EmailTextField.setText("abc@abc.com");
					EmailTextField.setForeground(Color.GRAY);
				}
				if(BirthtextField.getText().isEmpty())
				{
					BirthtextField.setText("YYYY-MM-DD");
					BirthtextField.setForeground(Color.GRAY);
				}
			}
		});
		frmManageClients.setTitle("... Manage Clients > Add Client");
		frmManageClients.setBounds(100, 100, 407, 474);
		frmManageClients.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frmManageClients.getContentPane().setLayout(null);
		
		FirstnameTextField = new JTextField();
		FirstnameTextField.setBounds(108, 39, 184, 20);
		frmManageClients.getContentPane().add(FirstnameTextField);
		FirstnameTextField.setColumns(10);
		
		LastnameTextField = new JTextField();
		LastnameTextField.setBounds(108, 70, 184, 20);
		frmManageClients.getContentPane().add(LastnameTextField);
		LastnameTextField.setColumns(10);
		
		PhoneTextField = new JTextField();
		PhoneTextField.setBounds(108, 130, 184, 20);
		frmManageClients.getContentPane().add(PhoneTextField);
		PhoneTextField.setColumns(10);
		
		EmailTextField = new JTextField();
		EmailTextField.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if(EmailTextField.getText().equals("abc@abc.com") && EmailTextField.getForeground()==Color.GRAY)
				{
					EmailTextField.setText("");
					EmailTextField.setForeground(Color.BLACK);
				}
				
			}
		});
		EmailTextField.setBounds(108, 161, 184, 20);
		frmManageClients.getContentPane().add(EmailTextField);
		EmailTextField.setColumns(10);
		EmailTextField.setText("abc@abc.com");
		EmailTextField.setForeground(Color.GRAY);
		
		
		IDTextField = new JTextField();
		IDTextField.setBounds(108, 192, 184, 20);
		frmManageClients.getContentPane().add(IDTextField);
		IDTextField.setColumns(10);
		
		BirthtextField = new JTextField();
		BirthtextField.addMouseListener(new MouseAdapter() {
			@Override
			/**
			 * Listener for the birthdate text field.
			 * When someone clicks the field, remove its content "YYYY-MM-DD";
			 */
			public void mouseClicked(MouseEvent arg0) {
				if(BirthtextField.getText().equals("YYYY-MM-DD"))
				{
					BirthtextField.setText("");
					BirthtextField.setForeground(Color.BLACK);
				}
			}
		});
		BirthtextField.setBounds(108, 223, 184, 20);
		frmManageClients.getContentPane().add(BirthtextField);
		BirthtextField.setColumns(10);
		BirthtextField.setText("YYYY-MM-DD");
		BirthtextField.setForeground(Color.GRAY);
		
		JLabel lblBirth = new JLabel("Birthdate :");
		lblBirth.setBounds(29, 226, 69, 14);
		frmManageClients.getContentPane().add(lblBirth);
		
		JLabel lblFirstName = new JLabel("First Name :");
		lblFirstName.setBounds(29, 42, 94, 14);
		frmManageClients.getContentPane().add(lblFirstName);
		
		JLabel lblLastName = new JLabel("Last Name :");
		lblLastName.setBounds(29, 73, 94, 14);
		frmManageClients.getContentPane().add(lblLastName);
		
		JLabel lblArea = new JLabel("Area :");
		lblArea.setBounds(29, 105, 94, 14);
		frmManageClients.getContentPane().add(lblArea);
		
		JLabel lblPhone = new JLabel("Phone :");
		lblPhone.setBounds(29, 133, 94, 14);
		frmManageClients.getContentPane().add(lblPhone);
		
		JLabel lblEmail = new JLabel("Email :");
		lblEmail.setBounds(29, 164, 94, 14);
		frmManageClients.getContentPane().add(lblEmail);
		
		JLabel lblId = new JLabel("ID :");
		lblId.setBounds(29, 195, 46, 14);
		frmManageClients.getContentPane().add(lblId);
		
		JCheckBox chckbxAllow = new JCheckBox("Allow future addressing");
		chckbxAllow.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(chckbxAllow.isSelected())
				{
					CategoryCheckboxList.setEnabled(true);
					//scroller.setEnabled(true);
				}
				else
				{
					CategoryCheckboxList.setEnabled(false);
					//scroller.setEnabled(false);
				}
			}
		});
		chckbxAllow.setBounds(108, 250, 184, 23);
		frmManageClients.getContentPane().add(chckbxAllow);
		
		JButton btnConfirm = new JButton("Confirm");
		btnConfirm.addActionListener(new ActionListener() {
			/**
			 * Listener for the confirm button.
			 * When a click is occurred, check the following inputs.
			 * > First name not null.
			 * > Address not null.
			 * > ID not null and valid.
			 * > Phone is valid.
			 * > Birthdate is valid.
			 * 
			 * If everything is good, call controller function.
			 */
			public void actionPerformed(ActionEvent arg0) {
				boolean ok = true;
				if(FirstnameTextField.getText().trim().equals("") || ValidateFirstOrLastName(FirstnameTextField.getText())==0)
				{
					lblFirstName.setForeground(Color.RED);
					ok = false;
				}
				else
					lblFirstName.setForeground(Color.BLACK);
				if(!LastnameTextField.getText().trim().isEmpty() && ValidateFirstOrLastName(LastnameTextField.getText())==0)
				{
					lblLastName.setForeground(Color.RED);
					ok = false;
				}
				else
					lblLastName.setForeground(Color.BLACK);
				if(areacomboBox.getSelectedIndex()==-1 || ((String)areacomboBox.getSelectedItem()).equals("Select an area..."))
				{
					lblArea.setForeground(Color.RED);
					ok = false;
				}
				else
					lblArea.setForeground(Color.BLACK);
				if(EmailTextField.getText().trim().equals("") || (EmailTextField.getForeground()==Color.GRAY && !EmailTextField.getText().isEmpty()) || ValidateEmail(EmailTextField.getText())==0)
				{
					lblEmail.setForeground(Color.RED);
					ok = false;
				}
				else
					lblEmail.setForeground(Color.BLACK);
				if(ValidateIDorPhone(IDTextField.getText())==0)
				{
					lblId.setForeground(Color.RED);
					ok = false;
				}
				else
					lblId.setForeground(Color.BLACK);
				if(ValidateIDorPhone(PhoneTextField.getText())==0)
				{
					lblPhone.setForeground(Color.RED);
					ok = false;
				}
				else
					lblPhone.setForeground(Color.BLACK);
				if(ValidateBirth(BirthtextField.getText())==0)
				{
					lblBirth.setForeground(Color.RED);
					ok = false;
				}
				else
					lblBirth.setForeground(Color.BLACK);

				if(ok)
				{
					AddClientController.addClient(FirstnameTextField.getText(), LastnameTextField.getText(), (String)areacomboBox.getSelectedItem(), PhoneTextField.getText(), EmailTextField.getText(), IDTextField.getText(),chckbxAllow.isSelected(),BirthtextField.getText());
					ArrayList<String> custcategories = new ArrayList<String>();
					custcategories.add(IDTextField.getText());
					for (int i=0;i<CategoryCheckboxList.objs.size();i++)
						if (CategoryCheckboxList.objs.get(i).getSlected()==1)
							custcategories.add(CategoryCheckboxList.objs.get(i).getName().substring(0, CategoryCheckboxList.objs.get(i).getName().indexOf(" ")));
					AddClientController.addClientCategories(custcategories);
				}
			}
		});
		btnConfirm.setBounds(203, 410, 89, 23);
		frmManageClients.getContentPane().add(btnConfirm);
		
		JButton btnCancel = new JButton("Cancel");
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				frmManageClients.dispose();
				goBack();
			}
		});
		btnCancel.setBounds(29, 410, 89, 23);
		frmManageClients.getContentPane().add(btnCancel);
		
		areacomboBox = new JComboBox();
		areacomboBox.setModel(new DefaultComboBoxModel(new String[] {"Please select an area"}));
		areacomboBox.setBounds(108, 99, 184, 20);
		frmManageClients.getContentPane().add(areacomboBox);
		
		comboBox = new JComboBox();
		comboBox.addActionListener(new ActionListener() {
			/**
			 * Listener for the combo box of external clients.
			 * When a click is occurred update the text fields according to the customer chosen.

			 * If chosen is the first one, delete all content from text fields.
			 */
			public void actionPerformed(ActionEvent arg0) {
				if(comboBox.getSelectedIndex()!=0)
				{
					Customer c = (Customer) comboBox.getSelectedItem();
					IDTextField.setText(c.getId());
					FirstnameTextField.setText(c.getFirstName());
					LastnameTextField.setText(c.getLastName());
					PhoneTextField.setText(c.getPhone());
					EmailTextField.setText(c.getEmail());
					areacomboBox.setSelectedItem((c.getAddress()));
					chckbxAllow.setSelected(c.getPermit());
					BirthtextField.setText(c.getBirthdate());
					lblBirth.setForeground(Color.BLACK);
					lblPhone.setForeground(Color.BLACK);
					lblId.setForeground(Color.BLACK);
					lblEmail.setForeground(Color.BLACK);
					lblArea.setForeground(Color.BLACK);
					lblLastName.setForeground(Color.BLACK);
					lblFirstName.setForeground(Color.BLACK);
					EmailTextField.setForeground(Color.BLACK);
					BirthtextField.setForeground(Color.BLACK);
					IDTextField.setEditable(false);
					FirstnameTextField.setEditable(false);
					LastnameTextField.setEditable(false);
					PhoneTextField.setEditable(false);
					EmailTextField.setEditable(false);
					areacomboBox.setEnabled(false);
					chckbxAllow.setEnabled(false);
					BirthtextField.setEditable(false);
					if(chckbxAllow.isSelected())
					{
						CategoryCheckboxList.setEnabled(true);
					}
					else
					{
						CategoryCheckboxList.setEnabled(false);
					}
				}
				else
				{
					IDTextField.setText("");
					FirstnameTextField.setText("");
					LastnameTextField.setText("");
					PhoneTextField.setText("");
					EmailTextField.setText("abc@abc.com");
					EmailTextField.setForeground(Color.GRAY);
					areacomboBox.setSelectedIndex(0);
					chckbxAllow.setSelected(false);
					BirthtextField.setText("YYYY-MM-DD");
					BirthtextField.setForeground(Color.GRAY);
					lblBirth.setForeground(Color.BLACK);
					lblPhone.setForeground(Color.BLACK);
					lblId.setForeground(Color.BLACK);
					lblEmail.setForeground(Color.BLACK);
					lblArea.setForeground(Color.BLACK);
					lblLastName.setForeground(Color.BLACK);
					lblFirstName.setForeground(Color.BLACK);
					IDTextField.setEditable(true);
					FirstnameTextField.setEditable(true);
					LastnameTextField.setEditable(true);
					PhoneTextField.setEditable(true);
					EmailTextField.setEditable(true);
					areacomboBox.setEnabled(true);
					chckbxAllow.setEnabled(true);
					BirthtextField.setEditable(true);
					CategoryCheckboxList.setEnabled(false);
				}
			}
		});
		comboBox.setBounds(107, 8, 185, 20);
		frmManageClients.getContentPane().add(comboBox);
		
		UpdateClientController.getExternalClients();
		
		JLabel lblOptional = new JLabel("Optional :");
		lblOptional.setBounds(29, 11, 69, 14);
		frmManageClients.getContentPane().add(lblOptional);
		
		JButton btnRefresh = new JButton("Refresh");
		btnRefresh.addActionListener(new ActionListener() {
			/**
			 * Listener for the refresh button.
			 * Reset all text fields.
			 */
			public void actionPerformed(ActionEvent e) {
				//UpdateClientController.getExternalClients();
				ManageCategoriesController.getProductCategories();
				MaintainingResidentialAreaController.getAreas();
				CategoryCheckboxList.setEnabled(false);
				IDTextField.setText("");
				FirstnameTextField.setText("");
				LastnameTextField.setText("");
				PhoneTextField.setText("");
				EmailTextField.setText("abc@abc.com");
				EmailTextField.setForeground(Color.GRAY);
				areacomboBox.setSelectedIndex(0);
				chckbxAllow.setSelected(false);
				BirthtextField.setText("YYYY-MM-DD");
				BirthtextField.setForeground(Color.GRAY);
				lblBirth.setForeground(Color.BLACK);
				lblPhone.setForeground(Color.BLACK);
				lblId.setForeground(Color.BLACK);
				lblEmail.setForeground(Color.BLACK);
				lblArea.setForeground(Color.BLACK);
				lblLastName.setForeground(Color.BLACK);
				lblFirstName.setForeground(Color.BLACK);
				comboBox.setSelectedIndex(0);
			}
		});
		btnRefresh.setBounds(302, 8, 79, 20);
		frmManageClients.getContentPane().add(btnRefresh);
		MaintainingResidentialAreaController.getAreas();
		
		
		CategoryList = new ArrayList<CheckBoxObject>();
		CategoryCheckboxList = new CheckBoxJList(CategoryList);
		defModel = new DefaultListModel();
		CategoryCheckboxList.setModel (defModel);
	    
		    for (int i=0;i<CategoryList.size();i++)
	        defModel.addElement (CategoryList.get(i));

		    CategoryCheckboxList.setEnabled(false);
		    scroller =
	        new JScrollPane (CategoryCheckboxList,
	                        ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
	                        ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
	 
		scroller.setBounds(108, 280, 184, 119);
		
		frmManageClients.getContentPane().add(scroller);
		
		JLabel lblInterests = new JLabel("Interests :");
		lblInterests.setBounds(29, 282, 69, 14);
		frmManageClients.getContentPane().add(lblInterests);
		
		ManageCategoriesController.getProductCategories();
		
		frmManageClients.setVisible(true);
	}

	@SuppressWarnings("unchecked")
	@Override
	/**
	 * AbstractGUI overridden method for getting a reply from server 
	 */
	public void getReply(Object r) {
		if(((Reply)r).command.equals(Command.ADD_CLIENT))
		{
			
			if (((Reply)r).result.equals(Result.OK))
			{
				System.out.println("New client added successfully!");
				JOptionPane.showMessageDialog(frmManageClients, "New client added successfully", "CCRM Add Client", JOptionPane.INFORMATION_MESSAGE);
				goBack();
			}
			else
			{
				System.out.println("ID already exists in DB!");
				JOptionPane.showMessageDialog(frmManageClients, "ID already exists in DB", "CCRM Add Client", JOptionPane.ERROR_MESSAGE);
			}
		}
		
		else if(((Reply)r).command.equals(Command.GET_AREAS))
		{
			String tmp;
			areasList=(ArrayList<Area>) ((Reply)r).result;
			areacomboBox.removeAllItems();
			areacomboBox.addItem("Select an area...");
			for(int i=0;i<areasList.size();i++)
			{
				tmp = areasList.get(i).getAreaName();
				areacomboBox.addItem(tmp);
			}
		}
		else if(((Reply)r).command.equals(Command.GET_EXTERNAL_CLIENTS))
		{
			res = (ArrayList<Customer>) ((Reply)r).result;
			comboBox.removeAllItems();
			comboBox.addItem("List of potential clients");
			for(int i=0;i<res.size();i++)
			{
				comboBox.addItem(res.get(i));
			}
		}
		else if(((Reply)r).command.equals(Command.GET_PRODUCT_CATEGORIES))
		{		    
		    result =(ArrayList<Category>) ((Reply)r).result;
			if(!CategoryList.isEmpty())
				CategoryList = new ArrayList<CheckBoxObject>();
			for(int i=0;i<result.size();i++)
				CategoryList.add(new CheckBoxObject(result.get(i).getCategoryid()+" "+result.get(i).getCategoryName(), 0));
			defModel.removeAllElements();
		    for (int i=0;i<CategoryList.size();i++)
		        defModel.addElement (CategoryList.get(i).getName());
		}
	}
	
	/**
	 * Method for checking if ID or phone is valid.
	 * Both must be not null and contain only numbers.
	 */
	public int ValidateIDorPhone(String id)
	{
		int i;
		if(id.length()==0)
			return 0;
		for (i=0;i<id.length();i++)
			if(id.charAt(i)>'9' || id.charAt(i)<'0')
				return 0;
		return 1;
	}
	/**
	 * Method for checking if birthdate is valid.
	 * It must be not null and in the form of YYYY-MM-DD, and contain only numbers.
	 */
	public int ValidateBirth(String birth)
	{
		int i,year,month,day;
		if(birth.length()!=10)
			return 0;
		if(birth.charAt(4)!='-' || birth.charAt(7)!='-')
			return 0;
		for (i=0;i<birth.length();i++)
			if(i!=4 && i!=7)
				if(birth.charAt(i)>'9' || birth.charAt(i)<'0')
					return 0;
		year = Integer.parseInt(birth.substring(0, 4));
		month = Integer.parseInt(birth.substring(5, 7));
		day = Integer.parseInt(birth.substring(8, 10));
		if(year<=0 || month>12 || month<=0 || day>31 || day<=0)
			return 0;
		return 1;
	}
	/**
	 * Method for checking if first or last name is valid.
	 * It must contain only letters a-z or A-Z.
	 */
	public int ValidateFirstOrLastName(String text)
	{
		for(int i=0;i<text.length();i++)
		{
			if(!((text.charAt(i)>='a' && text.charAt(i)<='z') || (text.charAt(i)>='A' && text.charAt(i)<='Z') || text.charAt(i)==' '))
				return 0;
		}
		return 1;
	}

	/**
	 * Method for checking if email is valid.
	 * It must be not null and in the form of abc@abc.com.
	 */
	public int ValidateEmail(String email)
	{
		String tmp;
		int i=0;
		int length=email.length();
		
		if(!email.endsWith(".com")) return 0;
		while(i<email.length() && email.charAt(i)!='@')
		{
			if(!validChar(email.charAt(i))) return 0;
			i++;
		}
		if(i==0) return 0;
		i++;
		while(i<email.length() && email.charAt(i)!='.')
		{
			if(!validChar(email.charAt(i))) return 0;
			i++;
		}
		if(!validChar(email.charAt(i+1))) return 0;
		if(i==email.length()-1) return 0;
		else return 1;
	}
	
	/**
	 * Helping method for checking if email is valid.
	 * Validating each char.
	 */
	public boolean validChar(char c)
	{
		return ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c==' ');
	}
}
